//+-----------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation, 1998-1999
//
// FileName:            slide.h
//
// Created:             06/24/98
//
// Author:              phillu
//
// Discription:         This is the header file for the CrSlide transformation
//
// Change History:
// 06/24/98 PhilLu      Developed 1.0 version for Chromeffects
// 11/04/98 PaulNash    Moved from DT 1.0 codebase to IE5/NT5 DXTMSFT.DLL
// 01/25/99 a-matcal    Fixed property map entries.
// 05/10/99 a-matcal    Optimization.
// 10/24/99 a-matcal    Changed CSlide class to CDXTSlideBase and created two
//                      new classes CDXTSlide and CDXTSlideOpt to represent  
//                      non-optimized and optimized versions respectively.
//
//------------------------------------------------------------------------------

#ifndef __CRSLIDE_H_
#define __CRSLIDE_H_

#include "resource.h"

#define MAX_BOUNDS 2

typedef enum CRSLIDESTYLE
{
    CRSS_HIDE,
    CRSS_PUSH,
    CRSS_SWAP,
} CRSLIDESTYLE;




class ATL_NO_VTABLE CDXTSlideBase : 
    public CDXBaseNTo1,
    public IDispatchImpl<ICrSlide, &IID_ICrSlide, &LIBID_DXTMSFTLib, 
                         DXTMSFT_TLB_MAJOR_VER, DXTMSFT_TLB_MINOR_VER>,
    public CComPropertySupport<CDXTSlideBase>,
    public IObjectSafetyImpl2<CDXTSlideBase>,
    public ISpecifyPropertyPagesImpl<CDXTSlideBase>
{
private:

    SIZE            m_sizeInput;
    short           m_cBands;	
    CRSLIDESTYLE    m_eSlideStyle;

    // m_lCurSlideDist  This member variable is basically m_Progress multiplied
    //                  by the input surface width.  It's calculated once in 
    //                  OnInitInstData and then used throughout the Bounds 
    //                  Calculation functions.  
    // m_lPrevSlideDist The value of m_lCurSlideDist that was calculated for the
    //                  previous execute.

    long            m_lCurSlideDist;
    long            m_lPrevSlideDist;

    long            m_alInputIndex[MAX_BOUNDS];

    // m_aptOffset      This member variable holds the input offset for each 
    //                  set of bounds generated by the Bounds Calculation
    //                  functions.  The bounds generated represent areas of
    //                  the output surface.  This offset is used to specify the 
    //                  point on the input surface that corresponds to the
    //                  top-left point of the bounds.

    POINT           m_aptOffset[MAX_BOUNDS];

    CDXDBnds        m_abndsDirty[MAX_BOUNDS];
    ULONG           m_cbndsDirty;

    CComPtr<IUnknown> m_cpUnkMarshaler;

    unsigned    m_fOptimizationPossible : 1;

protected:

    unsigned    m_fOptimize             : 1;

private:

    // Functions to calculate optimized bounds when blending with output and
    // using only one band.

    HRESULT _CalcFullBoundsHide();
    HRESULT _CalcFullBoundsPush();
    HRESULT _CalcFullBoundsSwap();

    // Functions to calculate optimized bounds when blending is off and using
    // only one band.  (Push and Swap are not specially optimizable for this 
    // situation because every pixel on the output is changing.)

    HRESULT _CalcOptBoundsHide();

    // This function is used for surface picking and when using greater than
    // one band.

    void    _CalcBounds(long & offsetA, long & offsetB, long & widthA, 
                        long & widthB);

    // Functions to generate/update output surface.  _WorkProc_Optimized is 
    // used for the 1 band cases, and _WorkProc_Multiband is used for the 
    // cases where then number of bands is greater than 1.

    HRESULT _WorkProc_Optimized(const CDXTWorkInfoNTo1 & WI, BOOL * pbContinue);
    HRESULT _WorkProc_Multiband(const CDXTWorkInfoNTo1 & WI, BOOL * pbContinue);
  
public:

    CDXTSlideBase();

    DECLARE_GET_CONTROLLING_UNKNOWN()

    BEGIN_COM_MAP(CDXTSlideBase)
        COM_INTERFACE_ENTRY(ICrSlide)
        COM_INTERFACE_ENTRY(IDispatch)
        COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_cpUnkMarshaler.p)
        COM_INTERFACE_ENTRY(IDXEffect)
        COM_INTERFACE_ENTRY_IID(IID_IObjectSafety, IObjectSafetyImpl2<CDXTSlideBase>)
        COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages)
        COM_INTERFACE_ENTRY_CHAIN(CDXBaseNTo1)
    END_COM_MAP()

    BEGIN_PROPERTY_MAP(CDXTSlideBase)
        PROP_ENTRY("bands"            , 1, CLSID_CrSlidePP)
        PROP_ENTRY("slideStyle"       , 2, CLSID_CrSlidePP)
        PROP_PAGE(CLSID_CrSlidePP)
    END_PROPERTY_MAP()

    // CComObjecRootEx overrides

    HRESULT FinalConstruct();

    // CDXBaseNTo1 overrides

    HRESULT OnSurfacePick(const CDXDBnds & OutPoint, ULONG & ulInputIndex, 
                          CDXDVec & InVec);
    HRESULT OnSetup(DWORD dwFlags);
    HRESULT OnInitInstData(CDXTWorkInfoNTo1 & WorkInfo, ULONG & ulNumBandsToDo);
    HRESULT WorkProc(const CDXTWorkInfoNTo1 & WI, BOOL * pbContinue);
    HRESULT OnFreeInstData(CDXTWorkInfoNTo1 & WorkInfo);

    // ICrSlide methods

    STDMETHOD(get_slideStyle)(/*[out, retval]*/ BSTR *pVal);
    STDMETHOD(put_slideStyle)(/*[in]*/ BSTR newVal);
    STDMETHOD(get_bands)(/*[out, retval]*/ short *pVal);
    STDMETHOD(put_bands)(/*[in]*/ short newVal);

    // IDXEffect methods

    DECLARE_IDXEFFECT_METHODS(DXTET_MORPH)
};


class ATL_NO_VTABLE CDXTSlide :
    public CDXTSlideBase,
    public CComCoClass<CDXTSlide, &CLSID_CrSlide>,
    public IPersistStorageImpl<CDXTSlide>,
    public IPersistPropertyBagImpl<CDXTSlide>
{
public:

    CDXTSlide()
    {
        m_fOptimize = false;
    }

    // Using DECLARE_REGISTRY_RESOURCEID will make the transform available for
    // use but won't add it to the "Image DirectTransform" category in the 
    // registry.

    DECLARE_REGISTRY_RESOURCEID(IDR_DXTSLIDE)
    DECLARE_POLY_AGGREGATABLE(CDXTSlide)

    BEGIN_COM_MAP(CDXTSlide)
        COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
        COM_INTERFACE_ENTRY_IMPL(IPersistPropertyBag)
        COM_INTERFACE_ENTRY_CHAIN(CDXTSlideBase)
    END_COM_MAP()
};


class ATL_NO_VTABLE CDXTSlideOpt :
    public CDXTSlideBase,
    public CComCoClass<CDXTSlideOpt, &CLSID_DXTSlide>,
    public IPersistStorageImpl<CDXTSlideOpt>,
    public IPersistPropertyBagImpl<CDXTSlideOpt>
{
public:

    CDXTSlideOpt()
    {
        m_fOptimize = true;
    }

    DECLARE_REGISTER_DX_IMAGE_TRANS(IDR_DXTSLIDEOPT)
    DECLARE_POLY_AGGREGATABLE(CDXTSlideOpt)

    BEGIN_COM_MAP(CDXTSlideOpt)
        COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
        COM_INTERFACE_ENTRY_IMPL(IPersistPropertyBag)
        COM_INTERFACE_ENTRY_CHAIN(CDXTSlideBase)
    END_COM_MAP()
};

#endif //__CRSLIDE_H_
